var config  = require("./config.js");
var md5     = require("./md5.js");
var base64  = require("./base64.js");

var regexEnum =  {
    intege: "^-?[1-9]\\d*$",				//整数
    intege1: "^[1-9]\\d*$",					//正整数
    intege2: "^-[1-9]\\d*$",				//负整数
    num: "^([+-]?)\\d*\\.?\\d+$",			//数字
    num1: "^([1-9]\\d*|0)$",				//正数（正整数 + 0）
    num2: "^-([1-9]\\d*|0)$",				//负数（负整数 + 0）
    decmal: "^([+-]?)([1-9]\\d*|0)([.]{1}[0-9]{1,2})?$",			//浮点数
    decmal1: "^([1-9]\\d*|0)([.]{1}[0-9]{1,2})?$",	//正整数，正浮点数，0 (小数点两位)
    decmal2: "^-([1-9]\\d*|0)([.]{1}[0-9]{1,2})?$",  //同上，负

    passwd: "^[\@A-Za-z0-9\!\#\$\%\^\&\*\.\~\_]{6,20}$", //密码
    url: "^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$",	//url
    email: "^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$", //邮件
    mobile: "^(13|14|15|16|17|18|19)[0-9]{9}$",	//手机
    zipcode: "^\\d{6}$",						//邮编
    color: "^[a-fA-F0-9]{6}$",				//颜色
    tel: "^(([0\\+]\\d{2,3}-)?(0\\d{2,3})-)?(\\d{7,8})(-(\\d{3,}))?$",	//电话号码的函数(包括验证国内区号,国际区号,分机号)
    date: "^\\d{4}(\\-|\\/|\.)\\d{1,2}\\1\\d{1,2}$",					//日期
    qq: "^[1-9]*[1-9][0-9]*$",	//QQ号码

    chinese: "^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$",					//仅中文
    ascii: "^[\\x00-\\xFF]+$",				//仅ACSII字符
    ip4: "^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$",	//ip地址
    notempty: "^\\S+$",						//非空
    picture: "(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$",	//图片
    rar: "(.*)\\.(rar|zip|7zip|tgz)$",								//压缩文件

    letter: "^[A-Za-z]+$",					//字母
    letter_u: "^[A-Z]+$",					//大写字母
    letter_l: "^[a-z]+$",					//小写字母
    idcard: "^[1-9]([0-9]{14}|[0-9]{16}[0-9xX])$",	//身份证
    bankcard: "^[1-9]\\d*$",					//银行卡

    username: "^\\w+$",						//用来用户注册。匹配由数字、26个英文字母或者下划线组成的字符串
    ps_username: "^[\\u4E00-\\u9FA5\\uF900-\\uFA2D_\\w]+$" //中文、字母、数字 _
}
//验证
function valid(value, reg) {
	return (new RegExp(regexEnum[reg])).test(value) ? true : false;
}

//数据对象md5, isSign=1返回加密字符串，否返回对象data，data包含sign字段
function sign(data, isSign)
{
	if (!isSign) isSign = 0;
	if (data.r == undefined) data.r = Math.random();
    data.r = data.r.toFixed(10);
    data.version = config.version;
	
    var key = md5.md5(config.key).substr(0, 16);
	data.signature = md5.md5(JSON.stringify(data) + key);
    return isSign ? data.signature : data;
}

//错误处理
function error(msg, back) {
    if (!msg) msg = '';
    if (typeof back == 'undefined') back = 1;
    uni.redirectTo({
        url: '/pages/public/error?msg=' + msg + '&back=' + back,
    });
}

//request
function request(opts) {
    if (!opts || !opts.url) return;
    if (opts.url.substr(0, 4) != 'http') opts.url = url(opts.url);
    if (opts.header == undefined) opts.header = { 'content-type': 'application/json' };
    if (opts.method == undefined) opts.method = 'POST';
    if (opts.data == undefined) opts.data = {};
    else if (opts.data.signature == undefined) opts.data = sign(opts.data);

    //slient静默执行
    if (opts.silent !== true && opts.success != undefined) {
        var func = opts.success;
        opts.success = function (res) {
            if (typeof res.data == 'object') {
				if (res.data.success == -100) {
                    uni.redirectTo({
                        url: '/pages/index/error?msg=' + (res.data.msg != '' ? res.data.msg : '') + '&back=' + (res.data.back != '' ? res.data.back : 0) + '&clear=' + (res.data.clear != '' ? res.data.clear : 0),
                    });
                }
                else if (res.data.success == -1) {
                    uni.hideLoading();
                    uni.stopPullDownRefresh();
                    uni.showToast({
                        title: res.data.msg, mask: true, duration: 2500, icon: 'none'
                    });
                }
                else {
                    func(res);
                }
            }
            else {
                if (opts.error === true) uni.redirectTo({
                    url: '/pages/index/error?msg=页面开小差了，稍后再试吧',
                });
            }
        }
    }

    if (opts.silent !== true && opts.fail == undefined) {
        opts.fail = function (res) {
            if (opts.error === true) uni.redirectTo({
                url: '/pages/index/error?msg=页面开小差了，稍后再试吧',
            });
        }
    }
	

    return uni.request(opts);
}

//生成URL
function url(op, other) {
	if (!op) op = '';
	if (!other) other = '';

	var url = config.url;
	if(op)
	{
		url = url + 'com/' + op; 
		if (other != '') {
			if (typeof other == 'string') {
				url += (other.substring(0, 1) == '&' ? '' : '&') + other;
			}
			else if (typeof other == 'array') {
				for (var i in other) {
					url += '&' + i + '=' + other[i];
				}
			}
		}
	}

	return url;
}

//生成URL
function urlext(op, other) {
    if (!op) op = '';
    if (!other) other = '';

    var url = config.url;
    if (op) {
        url = url + op;
        if (other != '') {
            if (typeof other == 'string') {
                url += (url.indexOf('?') >= 0 ? '&' : '?') + other;
            }
            else if (typeof other == 'array') {
                for (var i in other) {
                    url += (url.indexOf('?') >= 0 ? '&' : '?') + i + '=' + other[i];
                }
            }
        }
    }

    return url;
}
//生成url
function urlweixin(a,op)
{
	var url = config.url;
	url += 'com.php?op='+a;
	if (typeof op == 'string') {
		url += (op.substring(0, 1) == '&' ? '' : '&') + op;
	}
	else if (typeof op == 'array') {
		for (var i in other) {
			url += '&' + i + '=' + op[i];
		}
	}
	return url;
}
//生成URL
function urltext($url,op) {
    if (!op) op = '';
    var url = config.url;
	var $arr=$url.split('/');
	var b = ['m','c','a'];
	var d = '';
	for(var i in $arr)
	{
		if($arr[i])
		{
			var a=b.shift();
			if(!a)break;
			d += a+'='+$arr[i]+'&';
		}
	} 
	
	url = url+'index.php?'+d.slice(0,-1);
    if (op != '') {
    	if (typeof op == 'object') {
    		var str = '';
    		for (var i in op) {
    			str += '&'+i+'='+op[i]; 
    		}
    		url += str;
    	}
    }
    return url;
}
//短信
function smscode(that, tp) {
	that.setData({
		mobile: '',
		smscodeType: tp,
		smscodeText: '获取验证码',
		smscodeDisabled: false,
		smscodeLoading: false,
		smscodeHidden: true,
		smscodeVal: '',
		smscodeTime: 59	
	});
	that.smscode = function (e) {
		var value = that.data.mobile.trim();
		if (value == '') {
			uni.showToast({
				title: '请输入手机号码',
				icon: 'none'
			})
			return false;
		}

		if (valid(value, 'mobile')) {
			that.setData({ smscodeHidden: false, smscodeUrl: config.url + 'api.php?op=captcha&code_len=4&font_size=18&mongo=1&mobile='+value })
		}
		else {
			uni.showToast({
				title: '手机号码有误',
				icon: 'none'
			})
			return false;
		}
	};
	that.smscodeChange = function(e) {
		that.setData({ smscodeUrl: config.url + 'api.php?op=captcha&code_len=4&font_size=18&mongo=1&mobile=' + that.data.mobile + '&r=' + Math.random() })
	};
	that.smscodeInput = function(e) {
		that.setData({ smscodeVal: e.detail.value });
	};
	that.smscodeBlur = function (e) {
		that.setData({ smscodeVal: e.detail.value });
	};
	that.smscodeConfirm = function (e) {
		if(that.data.smscodeVal.trim() != '')
		{
			var code = that.data.smscodeVal.trim();
			that.setData({ smscodeHidden: true, smscodeDisabled: true, smscodeLoading: true, smscodeVal: '' });			
			uni.request({
				url: url('common/sms'),
				header: { 'content-type': 'application/json' },
				method: 'POST',
				data: sign({
					mobile: that.data.mobile,
					type: that.data.smscodeType,
					code: code,
					mongo: 1,
					r: Math.random(),
				}),
				success: function (res) {
					if (res.data.success > 0) {
						that.setData({ smscodeLoading: false})
						that.smscodeCount();
						uni.showToast({
							title: '发送成功',
							icon: 'none'
						})						
					}
					else{
						that.setData({ smscodeDisabled: false, smscodeLoading: false });
						uni.showToast({
							title: res.data.msg,
							icon: 'none'
						})
					}
				}
			});
		}		
	};
	that.smscodeCancel = function (e) {
		that.setData({ smscodeHidden: true })
	};
	that.smscodeCount =  function() {
		var count = that.data.smscodeTime,
			clear;
		var time = function () {
			if (count == 0) {
				that.setData({ smscodeDisabled: false, smscodeLoading: false, smscodeText: '获取验证码'})
				clearInterval(clear);
			} else {
				that.setData({ smscodeText: count + '秒' })
				count--;
				clear = setTimeout(function () {
					time()
				}, 1000);
			}
		};
		time();
	};
	that.smscodeMask = function() {
	};
}

//补0
function formatNumber(n) {
	n = n.toString()
	return n[1] ? n : '0' + n
}

//格式时间 - time ： unixtime, isType: YYYY-mm-dd
function formatTime(time, isType, isMill) {
	if(!isType) isType = 0;
	if(!isMill) isMill = 0;
	var date = time ? new Date(time * (isMill ? 1 : 1000)) : new Date()
	const year = date.getFullYear()
	const month = date.getMonth() + 1
	const day = date.getDate()
	const hour = date.getHours()
	const minute = date.getMinutes()
	const second = date.getSeconds()
	
	var ymd = [year, month, day].map(formatNumber).join('-');
	var his = [hour, minute, second].map(formatNumber).join(':');
	
	if(isType == 1) return ymd
	else if(isType == 2) return his
	else return ymd + ' ' + his
}

function fmtTime(unix_time, fmt) 
{
	if(!unix_time) unix_time = new Date().getTime();
	if(!fmt) fmt = 'yyyy-mm-dd hh:ii:ss';	
	unix_time = parseInt(unix_time);
	if(String(unix_time).length == 10) unix_time *= 1000;
    var date = new Date(unix_time);

    var o = {
        "m+": date.getMonth() + 1, //月份 
        "d+": date.getDate(), //日 
        "h+": date.getHours(), //小时 
        "i+": date.getMinutes(), //分 
        "s+": date.getSeconds(), //秒 
        "S": date.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

//格式手机号
function formatMobile(val) {
    return isEmpty(val) ? "" : val.substr(0, 3) + '****' + val.substr(-4);
}

//是否为空
function isEmpty(data) {
	data = data + ''
	if (null == data || (data=data.trim(), "" == data)) {
		return true;
	}
	return false;
}

//是否在数组中
function inArray(needle, array, bool) {
	if (typeof needle == "string" || typeof needle == "number") {
		for (var i in array) {
			if (needle === array[i]) {
				if (bool) {
					return i;
				}
				return true;
			}
		}
		return false;
	}
}

//对象合并
function objectExtend (o, n) {
	for (var p in n) {
		if (n.hasOwnProperty(p)) o[p] = n[p];
	}
	return o;
}

//字典 对象转数据
function dictConvert(data, checkArr){
	if (!checkArr) checkArr = [];
	var d = [];
	for(var i in data)
	{
		d.push({id: i, name: data[i], checked: inArray(i,checkArr)})
	}
	return d;
}
//从二组数据中根据Index删除一项
function arrayDelByIndex(data, index)
{
    var arr = [];
    for(var i in data) if(i!=index) arr.push(data[i]);
    return arr;
}
//从二组数据中根据ID删除一项
function arrayDelById(data, id)
{
    var arr = [];
    for(var i in data) if(data[i].id!=id) arr.push(data[i]);
    return arr;
}
//从二组数据中根据ID取索引
function arrayIndexById(data, id) {
    var arr = [];
    for (var i in data) if (data[i].id == id) return i;
}
//取父窗口对象, 0=本页面，-1=上级，-2=上上级，以此推(小程序默认是从-2，-3....)
function pageObj(pre)
{
	if(pre === 0) pre = 0;
    else if(!pre) pre = -1; //默认是上级
    var pages = getCurrentPages();
    return pages[pages.length + pre - 1];
}
//str md5
function strMd5(strings)
{
    return md5.md5(strings);
}
//str encode
function strEncode(strings) 
{
    var key = md5.md5(config.key).substring(0, 16);
    var strings = base64.encode(strings);
    var len = key.length;
    var code = '';
    for (var i = 0; i < strings.length; i++) {
        var k = i % len;
        code += String.fromCharCode(strings.charCodeAt(i) ^ key.charCodeAt(k));
    }
    return base64.encode(code);
}
//str decode
function strDecode(strings) 
{
    var key = md5.md5(config.key).substring(0, 16);
    var strings = base64.decode(strings);
    var len = key.length;
    var code = '';
    for (var i = 0; i < strings.length; i++) {
        var k = i % len;
        code += String.fromCharCode(strings.charCodeAt(i) ^ key.charCodeAt(k));
    }
    return base64.decode(code);
}
//对象转url参数
function queryParams(param, key) {
	if(param==null) return '';
	var paramStr = '';
	var t = typeof (param);
	if (t == 'string' || t == 'number' || t == 'boolean') {
		paramStr += '&' + key + '=' + encodeURIComponent(param);
	} else {
		for (var i in param) {
			var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
			paramStr += queryParams(param[i], k);	
		}
	}
	return paramStr;//最前面会有一个&
}

//APP pullToRefresh
function pullToRefresh(state)
{
	// #ifdef APP-PLUS
	pageObj(0).$getAppWebview().setStyle({  
		pullToRefresh: {  
			support: state
		}  
	}); 
	// #endif	
}

//常用UI
var ui = {
	back: function(delta, time) {
		if(!delta) delta = 1;
		if(!time) time = 0;
		setTimeout(function(){
			uni.navigateBack({ delta: delta })	
		}, time)
	},
	load: function(title, options) {
		if(!title) title = '正在加载'
		var opts = objectExtend({title: title, mask: true}, options)
		uni.showLoading(opts)
	},
	hideLoad: function() {
		uni.hideLoading()
	},
	toast: function(title, options){
		if(!title) title = '参数有误'
		var opts = objectExtend({title: title, mask: true, icon: 'none', position: 'bottom'}, options)
		uni.showToast(opts);
	},
	hideToast: function(){
		uni.showToast()
	}
}

//常用页面方式汇集
var tools = {
	//跳转
	go(e){
		uni.navigateTo({
			url: e.currentTarget.dataset.url
		})
	},
	//picker或其它之类
	set(e) {
		this[e.currentTarget.id] = e.detail.value
	},	
	//输入赋值
	input(e) {
		this[e.currentTarget.id] = e.detail.value.replace(/(^\s*)|(\s*$)/g, "")
	},	
	//预览图片
	previewImage(e, opts) {
		if(!opts) opts = {}
		var o = {}
		if(e) {
			o = { urls: [e.currentTarget.dataset.src] }
		}
		var a = Object.assign({}, o, opts);		
		uni.previewImage(a);
	}
}
//缓存
var  session={
	get(key){
		var data=uni.getStorageSync(key);
		let times = (new Date).getTime()/1000;
		times = parseInt(times);
		if(!data)
		{
			this.del(key);
			return null;
		}
		if(times>data.time&data.time!==0)
		{
			this.del(key);
			return null;
		}
		return data.value;
	},
	set(key,value,time=0){
		var data=uni.getStorageSync(key);
		let times = (new Date).getTime()/1000;
		times = parseInt(times);
		var data= {};
		if(time === 0)
		{
			data.time = 0;
		}else{
			data.time = times+time;
		}
		data.value = value;
		uni.setStorageSync(key,data);
	},
	del(key)
	{
		return uni.removeStorageSync(key);
		
	}
};
//扫描
var scanCode = {
	start(func){
		console.error('scanCode start', pageObj(0).route)
		uni.$on('scanCode', function(data){
			if(data.code != '') func.call(this, data);
		})			
	},
	close(){
		console.error('scanCode close', pageObj(0).route)
		uni.$off('scanCode') 
	}
}

/**************************************/
module.exports = {
	config: config,
    sign: sign,
	formatTime: formatTime,
	fmtTime: fmtTime,
	formatNumber: formatNumber,	
    formatMobile: formatMobile,
	isEmpty: isEmpty,
	inArray: inArray,
	valid: valid,
    error: error,    
    request: request,    
	url: url,
    urlext: urlext,
	urlweixin: urlweixin,
	urltext: urltext,
	smscode: smscode,
	dictConvert: dictConvert,
	objectExtend: objectExtend,
	arrayDelByIndex: arrayDelByIndex,
    arrayDelById: arrayDelById,
    arrayIndexById: arrayIndexById,
    pageObj: pageObj,
    strMd5: strMd5,
    strEncode: strEncode,
    strDecode: strDecode,
	queryParams: queryParams,
	pullToRefresh: pullToRefresh,
	ui: ui,
	tools: tools,
	scanCode: scanCode,
	session:session
}